package com.molichuxing.services.business.service.impl;

import com.molichuxing.services.business.convertor.Convert;
import com.molichuxing.services.business.dto.response.OrderDealerStatusInfoBizDto;
import com.molichuxing.services.business.dto.response.OrderTradeFlowBizDto;
import com.molichuxing.services.business.service.OrderTradeFlowBizService;
import com.molichuxing.services.contants.OrderRenegeFlowConst;
import com.molichuxing.services.contants.OrderStatusConst;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import com.molichuxing.services.utils.OrderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 交易流程服务
 *
 * @author zoumingyu
 * @date 2019年8月15日
 */
@Service("orderTradeFlowBizService")
public class OrderTradeFlowBizServiceImpl implements OrderTradeFlowBizService {
    private static final Logger logger = LoggerFactory.getLogger(OrderTradeFlowBizServiceImpl.class);

    @Resource
    private OrderExclusivelService orderExclusivelService;

    @Resource
    private OrderSubscribeService orderSubscribeService;

    @Resource
    private OrderStatusFlowService orderStatusFlowService;

    @Resource
    private OrderDealerService orderDealerService;

    @Resource
    private OrderScheduleService orderScheduleService;

    @Resource
    private OrderRenegeService orderRenegeService;

    @Resource
    private OrderReturnService orderReturnService;

    @Resource
    private LawsuitService lawsuitService;

    /**
     * 获取订阅里程订单交易流程
     *
     * @param orderCode          订单号
     * @param listType：列表类型-enum
     * @return
     * @throws Exception
     */
    @Override
    public List<OrderTradeFlowBizDto> getSubscribeOrderFlow(Long orderCode, OrderListTypeEnum listType)
            throws Exception {
        List<OrderTradeFlowBizDto> result = null;
        // 查询订阅里程订单信息
        OrderSubscribeDto orderSubscribe = orderSubscribeService.getOrderSubscribe(orderCode);
        if (orderSubscribe == null) {
            return result;
        }
        result = new ArrayList<>();
        // 查询订单流转信息
        List<OrderSubscribeStatusFlowDto> flowList = orderStatusFlowService.getSubscribeOrderStatusFlow(orderCode);
        if (flowList == null || flowList.isEmpty()) {
            return result;
        }
        // 查询类型
        List<OrderSubscribeStatusEnum> subscribeStatus = null;
        if (OrderListTypeEnum.TRADE_LIST.equals(listType)) {
            subscribeStatus = OrderStatusConst.TRADE_SUBSCRIBE_STATUS;
        } else if (OrderListTypeEnum.RETURN_LIST.equals(listType)) {
            subscribeStatus = OrderStatusConst.RETURN_SUBSCRIBE_STATUS;
        } else {
            subscribeStatus = new ArrayList<>();
        }

        for (OrderSubscribeStatusFlowDto orderStatusFlowDto : flowList) {
            // 判断类型
            if (!subscribeStatus.contains(orderStatusFlowDto.getOrderStatus())) {
                continue;
            }
            OrderTradeFlowBizDto orderTradeFlow = new OrderTradeFlowBizDto();
            // 订单交易流程状态
            orderTradeFlow.setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.COMPLETED);
            // 订单交易流程名
            orderTradeFlow
                    .setTradeFlowName(OrderUtil.transSubscribeFlowStatusName(orderStatusFlowDto.getOrderStatus(),
                            orderSubscribe.getParentOrderCode() == null ? false : true));
            // 执行时间
            orderTradeFlow.setExecutionTime(orderStatusFlowDto.getOrderModifiedTime());

            result.add(orderTradeFlow);
        }

        if (OrderSubscribeStatusEnum.TRADE_CANCELED.equals(orderSubscribe.getOrderStatus())
                || OrderSubscribeStatusEnum.TRADE_REJECTED.equals(orderSubscribe.getOrderStatus())
                || OrderSubscribeStatusEnum.TRADE_FINISH.equals(orderSubscribe.getOrderStatus())) {
            return result;
        }
        OrderTradeFlowBizDto orderTradeFlow = new OrderTradeFlowBizDto();
        if (OrderSubscribeStatusEnum.RETURN_FINISH.equals(orderSubscribe.getOrderStatus())) {
            // 订单交易流程状态
            orderTradeFlow.setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.COMPLETED);
        } else {
            // 订单交易流程状态
            orderTradeFlow.setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.CURRENT);
        }
        // 订单交易流程名
        orderTradeFlow.setTradeFlowName(orderSubscribe.getOrderStatus().getName());

        result.add(orderTradeFlow);
        return result;
    }


    /**
     * 获取专属里程订单交易流程
     *
     * @param orderCode          订单号
     * @param listType：列表类型-enum
     * @return
     * @throws Exception
     */
    @Override
    public List<OrderTradeFlowBizDto> getExclusivelOrderFlow(Long orderCode, OrderListTypeEnum listType)
            throws Exception {
        List<OrderTradeFlowBizDto> result = null;
        // 查询专属里程订单信息
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(orderCode);
        if (orderExclusivel == null) {
            return result;
        }
        if (OrderStatusConst.TRADE_EXCLUSIVEL_STATUS.contains(orderExclusivel.getOrderStatus())) {
            listType = OrderListTypeEnum.TRADE_LIST;
        } else if (OrderStatusConst.RENEGE_EXCLUSIVEL_STATUS.contains(orderExclusivel.getOrderStatus())) {
            listType = OrderListTypeEnum.RENEGE_LIST;
        } else if (OrderStatusConst.LAWSUIT_EXCLUSIVEL_STATUS.contains(orderExclusivel.getOrderStatus())) {
            listType = OrderListTypeEnum.LAWSUIT_LIST;
        }
        result = new ArrayList<>();
        if (OrderListTypeEnum.LAWSUIT_LIST.equals(listType)) {
            return lawsuitFlow(orderExclusivel, result);
        }
        // 查询订单流转信息
        List<OrderExclusivelStatusFlowDto> flowList = orderStatusFlowService.getExclusivelOrderStatusFlow(orderCode);
        if (flowList == null || flowList.isEmpty()) {
            return result;
        }
        // 查询类型
        List<OrderExclusivelStatusEnum> exclusivelStatus = null;
        if (OrderListTypeEnum.TRADE_LIST.equals(listType)) {
            exclusivelStatus = OrderStatusConst.TRADE_EXCLUSIVEL_STATUS;
        } else if (OrderListTypeEnum.RENEGE_LIST.equals(listType)) {
            return renegeFlow(orderExclusivel, flowList, result);
        } else {
            exclusivelStatus = new ArrayList<>();
        }
        for (OrderExclusivelStatusFlowDto orderStatusFlowDto : flowList) {
            // 判断类型
            if (!exclusivelStatus.contains(orderStatusFlowDto.getOrderStatus())) {
                continue;
            }
            OrderTradeFlowBizDto orderTradeFlow = new OrderTradeFlowBizDto();
            // 订单交易流程状态
            orderTradeFlow.setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.COMPLETED);
            // 订单交易流程名
            orderTradeFlow.setTradeFlowName(OrderUtil.transExclusivelFlowStatusName(
                    orderStatusFlowDto.getOrderStatus(), orderExclusivel.getPaymentMethod()));
            // 执行时间
            orderTradeFlow.setExecutionTime(orderStatusFlowDto.getOrderModifiedTime());
            result.add(orderTradeFlow);
        }
        if (OrderExclusivelStatusEnum.TRADE_CANCELED.equals(orderExclusivel.getOrderStatus())
                || OrderExclusivelStatusEnum.TRADE_REJECTED.equals(orderExclusivel.getOrderStatus())
                || OrderExclusivelStatusEnum.TRADE_FINISH.equals(orderExclusivel.getOrderStatus())) {
            return result;
        }
        OrderTradeFlowBizDto orderTradeFlow = new OrderTradeFlowBizDto();
        // 订单交易流程状态
        orderTradeFlow.setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.CURRENT);
        // 订单交易流程名
        orderTradeFlow.setTradeFlowName(orderExclusivel.getOrderStatus().getName());
        result.add(orderTradeFlow);

        return result;
    }

    /**
     * 诉讼订单流转
     *
     * @param orderExclusivel
     * @param result
     * @return
     */
    private List<OrderTradeFlowBizDto> lawsuitFlow(OrderExclusivelDto orderExclusivel,
                                                   List<OrderTradeFlowBizDto> result) {
        // 查询诉讼诉讼
        LawsuitDto lawsuit = lawsuitService.getLawsuit(orderExclusivel.getOrderCode());
        result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.COMPLETED,
                null, "申请诉讼", lawsuit.getLawsuitTime()));
        // 查询还车信息
        OrderReturnDto orderReturn = orderReturnService.getOrderReturn(orderExclusivel.getOrderCode());
        if (LawsuitStateEnum.FINISH.getValue() == lawsuit.getLawsuitState()) {
            // 已完成诉讼
            result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.COMPLETED,
                    null, RecycleStateEnum.getName(orderReturn.getRecycleState()), orderReturn.getReturnTime()));
            result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.COMPLETED,
                    null, "诉讼中", lawsuit.getFinishTime()));
            result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.COMPLETED,
                    null, "完成诉讼", lawsuit.getFinishTime()));
        } else {
            // 未完成诉讼
            if (orderReturn == null || RecycleStateEnum.FAIL.getValue() == orderReturn.getRecycleState()) {
                result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.CURRENT,
                        null, "诉讼中"));
                result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.WAIT,
                        null, "未收车"));
                result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.WAIT,
                        null, "完成诉讼"));
            } else {
                result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.COMPLETED,
                        null, RecycleStateEnum.getName(orderReturn.getRecycleState()), orderReturn.getReturnTime()));
                result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.CURRENT,
                        null, "诉讼中"));
                result.add(new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.WAIT,
                        null, "完成诉讼"));
            }
        }

        return result;
    }

    /**
     * 退租列表流转
     *
     * @param flowList
     * @param result
     * @return
     */
    private List<OrderTradeFlowBizDto> renegeFlow(OrderExclusivelDto orderExclusivel,
                                                  List<OrderExclusivelStatusFlowDto> flowList,
                                                  List<OrderTradeFlowBizDto> result) {
        // 判断当前订单状态
        if (OrderExclusivelStatusEnum.RENEGE_ACCEPTED.equals(orderExclusivel.getOrderStatus())) {
            // 待还车
            result = OrderRenegeFlowConst.RENEGE_ACCEPTED;
        } else if (OrderExclusivelStatusEnum.RENEGE_SETTLEMENT.equals(orderExclusivel.getOrderStatus())) {
            // 财务结算中
            result = OrderRenegeFlowConst.RENEGE_SETTLEMENT;
        } else if (OrderExclusivelStatusEnum.RENEGE_REFUND.equals(orderExclusivel.getOrderStatus())) {
            // 解除协议确认
            if (orderExclusivel.getCarId() != null && orderExclusivel.getCarId() > 0) {
                // 提车订单
                result = OrderRenegeFlowConst.RENEGE_REFUND_ONE;
            } else {
                // 未提车订单
                result = OrderRenegeFlowConst.RENEGE_REFUND_TWO;
            }
        } else if (OrderExclusivelStatusEnum.RENEGE_UNPAID.equals(orderExclusivel.getOrderStatus())) {
            // 收/退款
            if (orderExclusivel.getCarId() != null && orderExclusivel.getCarId() > 0) {
                // 提车订单
                result = OrderRenegeFlowConst.RENEGE_UNPAID_ONE;
            } else {
                // 未提车订单
                result = OrderRenegeFlowConst.RENEGE_UNPAID_TWO;
            }
        } else if (OrderExclusivelStatusEnum.RENEGE_FINISH.equals(orderExclusivel.getOrderStatus())) {
            // 退租已完成
            if (orderExclusivel.getCarId() != null && orderExclusivel.getCarId() > 0) {
                // 提车订单
                result = OrderRenegeFlowConst.RENEGE_FINISH_ONE;
            } else {
                // 未提车订单
                result = OrderRenegeFlowConst.RENEGE_FINISH_TWO;
            }
        }
//        result = new ArrayList<>(result);
        // 查询还车信息
        OrderReturnDto orderReturn = orderReturnService.getOrderReturn(orderExclusivel.getOrderCode());


        Integer key = null;

        for (int i = 0; i < result.size(); i++) {
            OrderTradeFlowBizDto orderTradeFlowBizDto = result.get(i);
            OrderExclusivelStatusEnum orderExclusivelStatusEnum = orderTradeFlowBizDto.getOrderStatus() == null
                    ? null : (OrderExclusivelStatusEnum) orderTradeFlowBizDto.getOrderStatus();

            if (OrderExclusivelStatusEnum.RENEGE_SETTLEMENT
                    .equals(orderExclusivelStatusEnum)) {
                if (orderReturn == null || RecycleStateEnum.FAIL.getValue() == orderReturn.getRecycleState()) {
                    key = i;
                } else {
                    orderTradeFlowBizDto.setTradeFlowName(RecycleStateEnum.getName(orderReturn.getRecycleState()));
                    orderTradeFlowBizDto.setExecutionTime(orderReturn.getReturnTime());
                }
                continue;
            }

            for (OrderExclusivelStatusFlowDto orderExclusivelStatusFlowDto : flowList) {
                if (orderExclusivelStatusFlowDto.getOrderStatus().equals(orderExclusivelStatusEnum)) {
                    orderTradeFlowBizDto.setExecutionTime(orderExclusivelStatusFlowDto.getOrderModifiedTime());
                }
            }
        }

        if (key != null) {
            result.remove(key);
        } else {
            result = result.stream().sorted(Comparator.comparing(OrderTradeFlowBizDto::getExecutionTime,
                    Comparator.nullsFirst(Comparator.reverseOrder())).reversed())
                    .collect(Collectors.toList());
        }

        return result;
    }

    /**
     * 获取经销商订单交易流程
     *
     * @param orderCode 订单号
     * @return
     * @throws Exception
     */
    @Override
    public List<OrderTradeFlowBizDto> getDealerOrderFlow(Long orderCode) throws Exception {
        List<OrderTradeFlowBizDto> result = new ArrayList<>();

        for (OrderDealerStatusEnum orderDealerStatus : OrderDealerStatusEnum.values()) {
            OrderTradeFlowBizDto orderTradeFlow = new OrderTradeFlowBizDto();
            // 订单交易流程状态
            orderTradeFlow.setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.WAIT);
            // 订单交易流程名
            orderTradeFlow.setTradeFlowName(orderDealerStatus.getName());
        }

        // 查询订阅里程订单信息
        OrderSubscribeDto orderSubscribe = orderSubscribeService.getOrderSubscribe(orderCode);
        if (orderSubscribe != null) {
            result = new ArrayList<>();
            // 查询订单流转信息
            List<OrderDealerDetailStatusDto> flowList = orderStatusFlowService.getDealerOrderStatusFlow(orderCode);
            if (flowList != null && flowList.size() > 0) {
                for (OrderDealerDetailStatusDto orderStatusFlowDto : flowList) {
                    for (OrderTradeFlowBizDto orderTradeFlow : result) {
                        if (orderStatusFlowDto.getOrderStatus().getName().equals(orderTradeFlow.getTradeFlowName())) {
                            // 订单交易流程状态-已执行状态
                            orderTradeFlow.setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.COMPLETED);
                            // 订单交易流程名-已执行状态
                            orderTradeFlow.setTradeFlowName(orderStatusFlowDto.getOrderStatus().getName());
                            // 执行时间-已执行状态
                            orderTradeFlow.setExecutionTime(orderStatusFlowDto.getOrderModifiedTime());
                        } else if (orderSubscribe.getOrderStatus().getName()
                                .equals(orderTradeFlow.getTradeFlowName())) {
                            // 订单交易流程状态-当前状态
                            orderTradeFlow.setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.CURRENT);
                            // 订单交易流程名-当前状态
                            orderTradeFlow.setTradeFlowName(orderSubscribe.getOrderStatus().getName());
                        }
                    }
                }
            }
        }

        return result;
    }


    @Override
    public OrderDealerStatusInfoBizDto getDealerOrderStatusFlow(Long orderCode) throws Exception {
        OrderDealerStatusInfoBizDto orderDealerStatusInfoBizDto = null;
        Integer status = orderDealerService.getOrderDealerStatus(orderCode);
        if (null == status) {
            return null;
        }
        orderDealerStatusInfoBizDto = new OrderDealerStatusInfoBizDto();
        BigDecimal payable;
        List<OrderDealerDetailStatusDto> orderDealerDetailStatusDtoList = orderStatusFlowService.getOrderDealerDetailStausFlowList(orderCode);
        orderDealerStatusInfoBizDto.setOrderCode(orderCode);
        orderDealerStatusInfoBizDto.setOrderStatusName(OrderDealerStatusEnum.getName(status));

        orderDealerStatusInfoBizDto.setOrderDealerStatusList(Convert.toOrderDealerStatusBizDto(orderDealerDetailStatusDtoList));

        if (status == OrderDealerStatusEnum.PREPAID_DOWN_PAYMENT.getValue()) {
            payable = orderScheduleService.getDealerFirstPayable(orderCode);
            orderDealerStatusInfoBizDto.setPayable(payable);
        }
        if (status == OrderDealerStatusEnum.COMPLETE.getValue()) {
            payable = orderScheduleService.getDealerPayable(orderCode);
            if (null != payable) {
                orderDealerStatusInfoBizDto.setPayable(payable);
            }
        }
        return orderDealerStatusInfoBizDto;
    }
}
